package plugins

import (
	"fmt"
	"net/http"
	"io/ioutil"
	"encoding/json"
	"github.com/olekukonko/tablewriter"
	"os"
	"bufio"
	"strings"
	"strconv"
	"os/exec"
	"time"
	"bytes"
)

const (
	Red = "\033[31m Error: "
	Green = "\033[32m Success:"
	Yellow = "\033[33m Warning:"
	Reset = "\033[0m"
)
type Plugin struct {
    RecordID string `json:"recordId"`
    CreatedAt int64 `json:"createdAt"`
    UpdatedAt int64 `json:"updatedAt"`
    Fields struct {
        PluginDesc string `json:"插件描述"`
        PluginName string `json:"插件名称"`
        RepoURL string `json:"仓库地址"`
        SubPath string `json:"相对地址"`
        PluginID int `json:"插件ID"`
		Dependence string `json:"安装依赖命令(脚本)"`
    } `json:"fields"`
}

type PluginResponse struct {
    Code int `json:"code"`
    Success bool `json:"success"`
    Data struct {
        Total int `json:"total"`
        Records []Plugin `json:"records"`
        PageNum int `json:"pageNum"`
        PageSize int `json:"pageSize"`
    } `json:"data"`
    Message string `json:"message"`
}


func listPlugins(pageNum *int, pageSize int,Token,TableID string) {
	// 定义指针变量
	pluginResponse := PluginResponse{}
	err := error(nil)
	prevPageNum := 0
	for {
		// 获取插件列表,如果请求页数一样，就不会重复请求
		if len(pluginResponse.Data.Records) == 0 || *pageNum != prevPageNum {
			pluginResponse, err = getPlugins(pageNum, pageSize,Token,TableID)
			if err != nil {
				//红色字体
				fmt.Printf(Red,"获取插件列表失败,请重新尝试", err, Reset)
				time.Sleep(2 * time.Second)
				return
			}
			prevPageNum = *pageNum
			//绿色字体
			// 取插件列表成功,状态码:,返回信息:
			//判断状态码是否为200，
			if pluginResponse.Code == 200 {
				//绿色字体
				fmt.Println(Green,"获取插件列表成功,状态码:", pluginResponse.Code, ",返回信息:", pluginResponse.Message, Reset)
			}

		}
			//fmt.打印状态码
		if pluginResponse.Code != 200 {
			//红色字体
			//取插件列表失败,状态码:,返回信息:
			fmt.Println(Red,"获取插件列表失败,状态码:", pluginResponse.Code, ",返回信息:", pluginResponse.Message, Reset)
			fmt.Println(Red,"共享API可能已经用完(月初刷新),请检查API或者更换API后尝试...", Reset)
			time.Sleep(3 * time.Second)
			return
		}
		// 如果没有插件数据则退出循环，
		if len(pluginResponse.Data.Records) == 0 {
			//红色字体
			//打印页码
			*pageNum = 1
			pluginResponse, err = getPlugins(pageNum, pageSize,Token,TableID)
			if err != nil {
				//红色字体
				fmt.Printf(Red,"获取插件列表失败,请重新尝试", err, Reset)
				time.Sleep(2 * time.Second)
				return
			}
			prevPageNum = *pageNum
		}
		// 创建表格
		table := tablewriter.NewWriter(os.Stdout)
		table.SetHeader([]string{"插件ID", "插件名称", "插件描述", "状态"})
		for _, plugin := range pluginResponse.Data.Records {
			// 如果插件github地址为空则跳过
			if plugin.Fields.RepoURL == "" {
				continue
			}
			// 处理字符过长截断
			if len(plugin.Fields.PluginDesc) > 60 {
				plugin.Fields.PluginDesc = plugin.Fields.PluginDesc[0:60] + "..."
			}
			// 判断是否已经安装
			status := ""
			_, err := os.Stat(plugin.Fields.SubPath)
			// 测试打印，是否存在目录
			// fmt.Println(plugin.Fields.SubPath)
			if err != nil {
				status = "\033[31m未安装\033[0m"
			} else {
				status = "\033[32m已安装\033[0m"
			}
			//清除颜色
			fmt.Print("\033[0m")
			table.Append([]string{strconv.Itoa(plugin.Fields.PluginID), plugin.Fields.PluginName, plugin.Fields.PluginDesc, status})
			table.SetColMinWidth(0, 10)
			table.SetColMinWidth(1, 20)
			table.SetColMinWidth(2, 60)
			table.SetColMinWidth(3, 8)
			//内容左
			table.SetAlignment(tablewriter.ALIGN_LEFT)
			//禁止自动换行
			table.SetAutoWrapText(false)

		}
		table.Render()

		// 提示用户翻页
		if len(pluginResponse.Data.Records) < pageSize {
			// 已经到最后一页, 重置页码
			// 安装插件部分,i u r 会用到,安装插件i ,更新插件u ,卸载插件r
			fmt.Printf("输入 i安装/更新插件 输入r卸载插件 输入q退出 回车下一页：")
			reader := bufio.NewReader(os.Stdin)
			text, _ := reader.ReadString('\n')
			text = strings.TrimSpace(text)
			if text == "q" {
				break
			}
			if text == "i" {
				fmt.Printf("输入插件ID：")
				reader := bufio.NewReader(os.Stdin)
				text, _ := reader.ReadString('\n')
				text = strings.TrimSpace(text)
				pluginID, _ := strconv.Atoi(text)
				installPlugin(pluginResponse,pluginID)
				*pageNum = *pageNum -1
			} else if text == "r" {
				fmt.Printf("输入插件ID：")
				reader := bufio.NewReader(os.Stdin)
				text, _ := reader.ReadString('\n')
				text = strings.TrimSpace(text)
				pluginID, _ := strconv.Atoi(text)
				uninstallPlugin(pluginResponse,pluginID)
				*pageNum = *pageNum -1
			} else if text == "" {
				*pageNum = 0
			}
			
		} else {
			fmt.Printf("输入 i安装/更新插件 输入r卸载插件 输入q退出 回车下一页：")
			reader := bufio.NewReader(os.Stdin)
			text, _ := reader.ReadString('\n')
			text = strings.TrimSpace(text)
			if text == "q" {
				break
			}
			if text == "i" {
				fmt.Printf("输入插件ID：")
				reader := bufio.NewReader(os.Stdin)
				text, _ := reader.ReadString('\n')
				text = strings.TrimSpace(text)
				pluginID, _ := strconv.Atoi(text)
				installPlugin(pluginResponse,pluginID)
				*pageNum = *pageNum -1
			} else if text == "r" {
				fmt.Printf("输入插件ID：")
				reader := bufio.NewReader(os.Stdin)
				text, _ := reader.ReadString('\n')
				text = strings.TrimSpace(text)
				pluginID, _ := strconv.Atoi(text)
				uninstallPlugin(pluginResponse,pluginID)
				*pageNum = *pageNum -1
			} 
			
			
		}
		(*pageNum)=(*pageNum)+1
		//打印page
		// fmt.Println(&pageNum)
	}

}



func getPlugins(pageNum *int, pageSize int,Token,TableID string) (PluginResponse, error) {
	url := fmt.Sprintf("https://api.vika.cn/fusion/v1/datasheets/%s/records?pageSize=%d&pageNum=%d", TableID, pageSize, *pageNum)
	method := "GET"
	client := &http.Client{}
	req, err := http.NewRequest(method, url, nil)

	if err != nil {
		return PluginResponse{}, err
	}
	req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", Token))
	req.Header.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36")

	res, err := client.Do(req)
	if err != nil {
		return PluginResponse{}, err
	}
	defer res.Body.Close()

	body, err := ioutil.ReadAll(res.Body)
	if err != nil {
		return PluginResponse{}, err
	}
	// 创建json解码器
	var pluginResponse PluginResponse
	err = json.Unmarshal(body, &pluginResponse)
	if err != nil {
		return PluginResponse{}, err
	}
	return pluginResponse, nil
}

func installPlugin(PluginResponse PluginResponse ,PluginID int) {
	// 获取插件列表
	pluginResponse := PluginResponse
	// 检查id是否存在，防止越界
	for _, plugin := range pluginResponse.Data.Records {
		if plugin.Fields.PluginID == PluginID {
			// 如果插件github地址为空则跳过
			if plugin.Fields.RepoURL == "" {
				continue
			}
			wd, _ := os.Getwd()
			fmt.Println("当前工作目录：", wd)
			// 判断是否已经安装
			_, err := os.Stat(plugin.Fields.SubPath)
			if err != nil {
				//询问是否安装
				fmt.Printf("是否安装插件 %s ?(y/n):",plugin.Fields.PluginName)
				var confirm string
				fmt.Scanln(&confirm)
				if confirm != "y" {
					//黄色
					fmt.Println(Yellow,"已取消安装...",Reset)
					time.Sleep(1 * time.Second)
					return
				}
				//安装插件
				RepoURL := CheckGithubUrl(plugin.Fields.RepoURL) //检测是否是github.com 域名，如果则自动加上代理
				install := fmt.Sprintf("git clone %s %s",RepoURL,plugin.Fields.SubPath)
				cmd := exec.Command("bash", "-c", install)
				cmd.Stdout = os.Stdout
				cmd.Stderr = os.Stderr
				cmd.Run()
				//安装依赖
				//判断是否存在依赖
				if plugin.Fields.Dependence != "" {
					//直接安装
					install := fmt.Sprintf("%s",plugin.Fields.Dependence)
					cmd := exec.Command("bash", "-c", install)
					yes := []byte("y\n")
					cmd.Stdin = ioutil.NopCloser(bytes.NewReader(yes))
					cmd.Stdout = os.Stdout
					cmd.Stderr = os.Stderr
					cmd.Run()
				}
				fmt.Println(Green,"执行完成...",Reset)
				time.Sleep(2 * time.Second)

			} else {
				fmt.Printf("插件已经安装更新插件 %s ?(y/n):",plugin.Fields.PluginName)
				var confirm string
				fmt.Scanln(&confirm)
				if confirm != "y" {
					// fmt.Println("已取消更新...")
					//黄色字体
					fmt.Println(Yellow,"已取消更新...",Reset)
					time.Sleep(1 * time.Second)
					return
				}
				//更新插件
				install := fmt.Sprintf("cd %s && git pull",plugin.Fields.SubPath)
				cmd := exec.Command("bash", "-c", install)
				cmd.Stdout = os.Stdout
				cmd.Stderr = os.Stderr
				cmd.Run()
				//安装依赖
				fmt.Println(Green,"执行完成...",Reset)
				time.Sleep(2 * time.Second)
			}

			return 

		}
	} 
	// fmt.Println("插件ID不存在,或者存在越界")
	//红色字体
	fmt.Println(Red,"插件ID不存在,或者存在越界",Reset)
	time.Sleep(1 * time.Second)
}

func uninstallPlugin(PluginResponse PluginResponse ,PluginID int) {
	// 获取插件列表
	pluginResponse := PluginResponse
	// 检查id是否存在，防止越界
	for _, plugin := range pluginResponse.Data.Records {
		if plugin.Fields.PluginID == PluginID {
			// 如果插件github地址为空则跳过
			if plugin.Fields.RepoURL == "" {
				continue
			}
			wd, _ := os.Getwd()
			fmt.Println("当前工作目录：", wd)
			// 判断是否已经安装
			_, err := os.Stat(plugin.Fields.SubPath)
			if err != nil {
				//红色字体
				fmt.Println(Red,"插件未安装",Reset)
				return
			} else {
				//询问是否卸载
				fmt.Printf("是否卸载插件 %s ?(y/n):",plugin.Fields.PluginName)
				var confirm string
				fmt.Scanln(&confirm)
				if confirm != "y" {
					//黄色字体
					fmt.Println(Yellow,"已取消卸载...",Reset)
					time.Sleep(2 * time.Second)
					return
				}
				//卸载插件
				install := fmt.Sprintf("rm -rf %s",plugin.Fields.SubPath)
				cmd := exec.Command("bash", "-c", install)
				cmd.Stdout = os.Stdout
				cmd.Stderr = os.Stderr
				cmd.Run()
				//按回车键继续
				fmt.Println(Green,"执行完成...",Reset)
				time.Sleep(2 * time.Second)
			}
			return 
		}
	} 
	// 红色字体,常量
	fmt.Println(Red,"插件ID不存在,或者存在越界",Reset)

}

//检测是否是github.com 域名，如果则自动加上代理
func CheckGithubUrl(rawurl string) string {
	if strings.Contains(rawurl, "github.com") {
		return "https://ghproxy.com/" + rawurl
	}
	return rawurl
}
// 云崽插件安装/卸载
func Yunzai_plugin(Go_Box_path,YunZaiPath,Token,TableID string) {
	os.Chdir(Go_Box_path)
	err := os.Chdir(YunZaiPath)
	if err != nil {
		// 红色字体
		fmt.Println(Red,"切换失败,Bot没有安装",Reset)
		time.Sleep(2 * time.Second)
		return
	}
	// 打印当前工作目录
	// 切换bot目录
	// listPlugins(1, 20,Token,TableID)
	// 定义指针变量
	pageNum := 1  //请求的页码
	pageSize := 23  //请求的数据量
	listPlugins(&pageNum, pageSize,Token,TableID)
	os.Chdir(Go_Box_path)
}



